Passed
Pull Request — master (#182)
by Mathieu
04:33
created

DateUtilsAdapter.isWeekend   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
import { Injectable } from '@nestjs/common';
2
import {
3
  format as fnsFormat,
4
  isWeekend as fnsIsWeekend,
5
  getDaysInMonth as fnsGetDaysInMonth,
6
  eachDayOfInterval,
7
  addDays
8
} from 'date-fns';
9
import { IDateUtils } from 'src/Application/IDateUtils';
10
11
@Injectable()
12
export class DateUtilsAdapter implements IDateUtils {
13
  public format(date: Date, format: string): string {
14
    return fnsFormat(date, format);
15
  }
16
17
  public getDaysInMonth(date: Date): number {
18
    return fnsGetDaysInMonth(date);
19
  }
20
21
  public isWeekend(date: Date): boolean {
22
    return fnsIsWeekend(date);
23
  }
24
25
  public getCurrentDate(): Date {
26
    return new Date();
27
  }
28
29
  public getCurrentDateToISOString(): string {
30
    return this.getCurrentDate().toISOString();
31
  }
32
33
  public addDaysToDate(date: Date, days: number): Date {
34
    return addDays(date, days);
35
  }
36
37
  public getWorkedDaysDuringAPeriod(start: Date, end: Date): Date[] {
38
    const dates: Date[] = [];
39
    const workedFreeDays: Date[] = [];
40
41
    for (let year = start.getFullYear(); year <= end.getFullYear(); year++) {
42
      workedFreeDays.push(...this.getWorkedFreeDays(year));
43
    }
44
45
    for (const day of eachDayOfInterval({ start, end })) {
46
      if (
47
        this.isWeekend(day) ||
48
        workedFreeDays.filter(d => d.toISOString() === day.toISOString())
49
          .length > 0
50
      ) {
51
        continue;
52
      }
53
54
      dates.push(day);
55
    }
56
57
    return dates;
58
  }
59
60
  public getWorkedFreeDays(year: number): Date[] {
61
    const fixedDays: Date[] = [
62
      new Date(`${year}-01-01`), // New Year's Day
63
      new Date(`${year}-05-01`), // Labour Day
64
      new Date(`${year}-05-08`), // Victory in 1945
65
      new Date(`${year}-07-14`), // National Day
66
      new Date(`${year}-08-15`), // Assumption
67
      new Date(`${year}-11-01`), // All Saints' Day
68
      new Date(`${year}-11-11`), // The Armistice
69
      new Date(`${year}-12-25`) // Christmas
70
    ];
71
72
    const easterDate = this.getEasterDate(year);
73
    const easterDays: Date[] = [
74
      addDays(easterDate, 1), // Easter Monday
75
      addDays(easterDate, 39) // Ascension
76
    ];
77
78
    return [...fixedDays, ...easterDays];
79
  }
80
81
  public getEasterDate(year: number): Date {
82
    const a = year % 19;
83
    const b = Math.floor(year / 100);
84
    const c = year % 100;
85
    const d = Math.floor(b / 4);
86
    const e = b % 4;
87
    const f = Math.floor((b + 8) / 25);
88
    const g = Math.floor((b - f + 1) / 3);
89
    const h = (19 * a + b - d - g + 15) % 30;
90
    const i = Math.floor(c / 4);
91
    const k = c % 4;
92
    const l = (32 + 2 * e + 2 * i - h - k) % 7;
93
    const m = Math.floor((a + 11 * h + 22 * l) / 451);
94
    const n0 = h + l + 7 * m + 114;
95
    const n = Math.floor(n0 / 31) - 1;
96
    const p = (n0 % 31) + 1;
97
98
    return new Date(year, n, p);
99
  }
100
101
  public getLeaveDuration(startDate: string, isStartsAllDay: boolean, endDate: string, isEndsAllDay: boolean): number {
102
    let duration = this.getWorkedDaysDuringAPeriod(
103
      new Date(startDate),
104
      new Date(endDate)
105
    ).length;
106
107
    if (false === isStartsAllDay) {
108
      duration -= 0.5;
109
    }
110
111
    if (false === isEndsAllDay && duration > 0.5) {
112
      duration -= 0.5;
113
    }
114
115
    return duration;
116
  }
117
}
118